﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SCS.DAL;
using SCS.Common.Models;
using System.Linq.Expressions;
namespace SCS.Business
{
    public class TeacherServices
    {
        IUnitOfWork _unitOfWork;
        public TeacherServices()
        {
            _unitOfWork = new UnitOfWork();
        }

        /// <summary>
        /// CountTeacher
        /// </summary>
        /// <param name="searchString">string</param>
        /// <returns>count</returns>
        public int CountTeacher(string searchString)
        {
            if (string.IsNullOrEmpty(searchString))
            {
                return _unitOfWork.Teacher.GetCount();
            }
            else
            {
                return _unitOfWork.Teacher.GetSearchCount(searchString);
            }
        }

        /// <summary>
        /// GetTeacher
        /// </summary>
        /// <param name="teacherID">teacherID</param>
        /// <returns>teacher</returns>
        public Teacher GetTeacher(int teacherID)
        {
            return _unitOfWork.Teacher.Get(m => m.teacherID == teacherID).FirstOrDefault();
        }

        /// <summary>
        /// SearchTeacherPaging
        /// </summary>
        /// <param name="pageNumber">pageNumber</param>
        /// <param name="pageSize">pageSize</param>
        /// <param name="searchString">searchString</param>
        /// <returns>teacher list</returns>
        public IEnumerable<Teacher> SearchTeacherPaging(int pageNumber, int pageSize, string searchString)
        {
            return _unitOfWork.Teacher.SearchTeacherPaging(pageNumber, pageSize, searchString);
        }

        /// <summary>
        /// GetAllTeacher
        /// </summary>
        /// <returns>teacher list</returns>
        public IEnumerable<Teacher> GetAllTeacher()
        {
            return _unitOfWork.Teacher.GetAll();
        }

        /// <summary>
        /// GetAllTeacherNoUserID
        /// </summary>
        /// <returns>teacher list</returns>
        public IEnumerable<Teacher> GetAllTeacherNoUserID()
        {
            return _unitOfWork.Teacher.GetAll().Where(m => m.userID == null);
        }

        /// <summary>
        /// GetAllClassInSchoolYears
        /// </summary>
        /// <returns>class list</returns>
        public IEnumerable<ClassInSchoolYear> GetAllClassInSchoolYears()
        {
            int maxSchoolYearID = _unitOfWork.ClassInSchoolYear.GetAll().Max(m => m.schoolYearID);
            return _unitOfWork.ClassInSchoolYear.GetAll().Where(m => m.schoolYearID == maxSchoolYearID);
        }

        /// <summary>
        /// GetAllSubject
        /// </summary>
        /// <returns>subject list</returns>
        public IEnumerable<Subject> GetAllSubject()
        {
            return _unitOfWork.Subject.GetAll();
        }

        /// <summary>
        /// GetAllSchoolYear
        /// </summary>
        /// <returns>school year list</returns>
        public IEnumerable<SchoolYear> GetAllSchoolYear()
        {
            return _unitOfWork.SchoolYear.GetAll();
        }

        /// <summary>
        /// GetAllTerm
        /// </summary>
        /// <returns>term list</returns>
        public IEnumerable<Term> GetAllTerm()
        {
            return _unitOfWork.Term.GetAll();
        }

        /// <summary>
        /// GetTeacherPaging
        /// </summary>
        /// <param name="pageNumber">pageNumber</param>
        /// <param name="pageSize">pageSize</param>
        /// <returns>teacher list</returns>
        public IEnumerable<Teacher> GetTeacherPaging(int pageNumber, int pageSize)
        {
            return _unitOfWork.Teacher.GetTeacherPaging(pageNumber, pageSize);
        }

        /// <summary>
        /// GetAllLearnerDataToStatistic
        /// </summary>
        /// <param name="teacherID">teacherID</param>
        /// <returns>Learner List</returns>
        public IEnumerable<Learner> GetAllLearnerDataToStatistic(int classID)
        {
            return _unitOfWork.Learner.GetAllOrderBy(m => m.learnerID).Where(m => m.classID == classID);
        }

        /// <summary>
        /// AddTeacher
        /// </summary>
        /// <param name="teacher">Teacher</param>
        /// <returns>bool</returns>
        public bool AddTeacher(Teacher teacher)
        {
            try
            {
                int id = _unitOfWork.Teacher.GetAll().Max(t => (int?)t.teacherID) ?? 0;
                teacher.teacherID = id + 1;
                _unitOfWork.Teacher.Add(teacher);
                _unitOfWork.Commit();
                return true;
            }
            catch (Exception e)
            {
                return false;
            }
        }

        /// <summary>
        /// UpdateTeacher
        /// </summary>
        /// <param name="teacher">Teacher</param>
        /// <returns>bool</returns>
        public bool UpdateTeacher(Teacher teacher)
        {
            try
            {
                _unitOfWork.Teacher.Update(teacher);
                _unitOfWork.Commit();
                return true;
            }
            catch (Exception e)
            {
                return false;
            }
        }

        /// <summary>
        /// DeleteTeacher
        /// </summary>
        /// <param name="ID">ID</param>
        /// <returns>bool</returns>
        public bool DeleteTeacher(int ID)
        {
            try
            {
                Teacher deleteTeacher = new Teacher();
                deleteTeacher = GetTeacher(ID);
                _unitOfWork.Teacher.Delete(deleteTeacher);
                _unitOfWork.Commit();
                return true;
            }
            catch (Exception e)
            {
                return false;
            }
        }

        /// <summary>
        /// AssignTeacher
        /// </summary>
        /// <param name="assignTeacher">TeachingAssignment</param>
        /// <returns>bool</returns>
        public bool AssignTeacher(TeachingAssignment assignTeacher)
        {
            try
            {
                int id = _unitOfWork.TeachingAssignment.GetAll().Max(t => (int?)t.teachingAssignmentID) ?? 0;
                assignTeacher.teachingAssignmentID = id + 1;
                _unitOfWork.TeachingAssignment.Add(assignTeacher);
                _unitOfWork.Commit();
                return true;
            }
            catch (Exception e)
            {
                return false;
            }
        }

        /// <summary>
        /// GetTeacher_Last
        /// </summary>
        /// <returns>teacher</returns>
        public Teacher GetTeacher_Last()
        {
            int id = _unitOfWork.Teacher.GetAll().Max(t => (int?)t.teacherID) ?? 0;
            return _unitOfWork.Teacher.Get(m => m.teacherID == id).FirstOrDefault();
        }

        //TeacherViewModels

        /// <summary>
        /// CountTeacherViewGrade
        /// </summary>
        /// <param name="firstDate">firstDate</param>
        /// <param name="lastDate">lastDate</param>
        /// <returns>count</returns>
        public int CountTeacherViewGrade(DateTime firstDate, DateTime lastDate)
        {
            if (firstDate == null || lastDate == null)
            {
                return _unitOfWork.Teacher.GetCount();
            }
            else
            {
                return _unitOfWork.Parent.GetSearchCount(firstDate, lastDate);
            }
        }

        /// <summary>
        /// CountTeacherViewGrade
        /// </summary>
        /// <param name="firstDate">firstDate</param>
        /// <param name="lastDate">lastDate</param>
        /// <param name="classID">classID</param>
        /// <returns>count</returns>
        public int CountTeacherViewGrade(DateTime firstDate, DateTime lastDate, int classID)
        {
            return _unitOfWork.Parent.GetSearchCount(firstDate, lastDate);
        }

        /// <summary>
        /// Grade
        /// </summary>
        /// <returns>grade list</returns>
        public IList<Grade> Grade()
        {
            return _unitOfWork.Grade.GetAll().OrderByDescending(m => m.createDate).ToList();
        }

        /// <summary>
        /// GradeByTeacherID
        /// </summary>
        /// <param name="classID">classID</param>
        /// <returns>grade list</returns>
        public IList<Grade> GradeByTeacherID(int classID)
        {
            return _unitOfWork.Grade.GetAll().Where(m => m.Learner.classID == classID).OrderByDescending(m => m.createDate).ToList();
        }

        /// <summary>
        /// GradeByTeacherID
        /// </summary>
        /// <param name="firstDate">firstDate</param>
        /// <param name="lastDate">lastDate</param>
        /// <param name="classID">classID</param>
        /// <returns>grade</returns>
        public IList<Grade> GradeByTeacherID(DateTime firstDate, DateTime lastDate, int classID)
        {
            return _unitOfWork.Grade.GetAll().Where(m => m.Learner.classID == classID
                                                 && m.createDate >= firstDate
                                                 && m.createDate <= lastDate).OrderByDescending(m => m.createDate).ToList();
        }

        /// <summary>
        /// Grade
        /// </summary>
        /// <param name="pageNumber">pageNumber</param>
        /// <param name="pageSize">pageSize</param>
        /// <param name="firstDate">firstDate</param>
        /// <param name="lastDate">lastDate</param>
        /// <returns>Grade</returns>
        public IList<Grade> Grade(int pageNumber, int pageSize, DateTime firstDate, DateTime lastDate)
        {
            return _unitOfWork.Parent.SearchGradeInTimePaging(pageNumber, pageSize, firstDate, lastDate).OrderByDescending(m => m.createDate).ToList();
        }

        /// <summary>
        /// GradesInClass
        /// </summary>
        /// <returns>Grade</returns>
        public IList<Grade> GradesInClass()
        {
            return _unitOfWork.Grade.GetAll().OrderBy(m => m.Learner.lastName).ToList();
        }

        /// <summary>
        /// GradesInClass
        /// </summary>
        /// <param name="termID">termID</param>
        /// <param name="classID">classID</param>
        /// <param name="subjectID">subjectID</param>
        /// <returns>grade</returns>
        public IList<Grade> GradesInClass(int termID, int classID, int subjectID)
        {
            return _unitOfWork.Parent.SearchGradesListPaging(termID, classID, subjectID).OrderBy(m => m.Learner.lastName).ToList();
        }

        /// <summary>
        /// TeachingAssignment
        /// </summary>
        /// <param name="classID">classID</param>
        /// <param name="schooYearID">schooYearID</param>
        /// <returns>Teaching Assign List</returns>
        public IList<TeachingAssignment> TeachingAssignment(int classID, int schooYearID)
        {
            return _unitOfWork.TeachingAssignment.Get(m => m.classID == classID && m.schoolYearID == schooYearID).ToList();
        }

        /// <summary>
        /// CommentInClass
        /// </summary>
        /// <returns>CommentInClass list</returns>
        public IList<CommentInClass> CommentInClass()
        {
            return _unitOfWork.Comment.GetAll().OrderByDescending(m => m.dateOfComment).ToList();
        }

        /// <summary>
        /// CountTeacherViewComment
        /// </summary>
        /// <param name="firstDate">firstDate</param>
        /// <param name="lastDate">lastDate</param>
        /// <returns>count</returns>
        public int CountTeacherViewComment(DateTime firstDate, DateTime lastDate)
        {
            if (firstDate == null || lastDate == null)
            {
                return _unitOfWork.Comment.GetCount();
            }
            else
            {
                return _unitOfWork.Comment.GetSearchCount(firstDate, lastDate);
            }
        }

        /// <summary>
        /// CommentInClass
        /// </summary>
        /// <param name="pageNumber">pageNumber</param>
        /// <param name="pageSize">pageSize</param>
        /// <param name="firstDate">firstDate</param>
        /// <param name="lastDate">lastDate</param>
        /// <returns>Comment In Class list</returns>
        public IList<CommentInClass> CommentInClass(int pageNumber, int pageSize, DateTime firstDate, DateTime lastDate)
        {
            return _unitOfWork.Comment.SearchGradeInTimePaging(pageNumber, pageSize, firstDate, lastDate);
        }

        /// <summary>
        /// getLearnerList
        /// </summary>
        /// <param name="classID">classID</param>
        /// <returns>learner list</returns>
        public IList<Learner> getLearnerList(int classID)
        {
            return _unitOfWork.Learner.GetAll().Where(m => m.classID == classID && m.parentID.HasValue).ToList();
        }

        /// <summary>
        /// GetGradeTypeIDByGradeTypeName
        /// </summary>
        /// <param name="gradeTypeName">gradeTypeName</param>
        /// <returns>GradeType</returns>
        public GradeType GetGradeTypeIDByGradeTypeName(string gradeTypeName)
        {
            return _unitOfWork.GradeType.Get(m => m.gradeTypeName == gradeTypeName).FirstOrDefault();
        }

        /// <summary>
        /// GetSubjectIDBySubjectName
        /// </summary>
        /// <param name="gradeTypeName">subjectName</param>
        /// <returns>Subject</returns>
        public Subject GetSubjectIDBySubjectName(string subjectName)
        {
            return _unitOfWork.Subject.Get(m => m.subjectName == subjectName).FirstOrDefault();
        }

        /// <summary>
        /// Add Grade
        /// </summary>
        /// <param name="teacher">Teacher</param>
        /// <returns>bool</returns>
        public bool AddGrade(Grade grade)
        {
            try
            {
                _unitOfWork.Grade.Add(grade);
                _unitOfWork.Commit();
                return true;
            }
            catch (Exception e)
            {
                return false;
            }
        }

        /// <summary>
        /// CountLearnerConsciousness
        /// </summary>
        /// <param name="flag">int</param>
        /// <param name="learnerID">int</param>
        /// <returns>count</returns>
        public int CountLearnerConsciousness(int flag, int learnerID)
        {
            if (flag == 1)
            {
                return _unitOfWork.Comment.GetAll().Where(m => m.isTalkDuringClass == true
                                                       && m.learnerID == learnerID).Count();
            }
            else if (flag == 2)
            {
                return _unitOfWork.Comment.GetAll().Where(m => m.incompleteHomework == true
                                                       && m.learnerID == learnerID).Count();
            }
            else
            {
                return _unitOfWork.Comment.GetAll().Where(m => m.isAbsent == true
                                                       && m.learnerID == learnerID).Count();
            }
        }
    }
}